package com.itstudio.portal.controller;

import com.itstudio.portal.entity.RestResponse;
import com.itstudio.portal.entity.dto.*;
import com.itstudio.portal.enums.HttpCodeEnum;
import com.itstudio.portal.exception.SystemException;
import com.itstudio.portal.service.UserService;
import com.itstudio.portal.utils.Const;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;

@RestController
@RequestMapping("/api/user")
public class UserController {

    @Autowired
    UserService userService;

    @Autowired
    StringRedisTemplate redisTemplate;

    //通过验证码登录
    @PostMapping("/loginByCode")
    public RestResponse loginByCode(@RequestBody LoginCodeDto login) {
        if(!StringUtils.hasText(login.getPhone()))
            return RestResponse.failure(HttpCodeEnum.PHONE_NOT_NULL);
        if(!StringUtils.hasText(login.getCode()))
            return RestResponse.failure(HttpCodeEnum.CODE_NOT_NULL);
        return userService.loginByCode(login);
    }

    //通过密码登录
    @PostMapping("/loginByPasswd")
    public RestResponse loginByPasswd(@RequestBody LoginPasswdDto login) {
        if(!StringUtils.hasText(login.getPhone()))
            return RestResponse.failure(HttpCodeEnum.PHONE_NOT_NULL);
        if(!userService.phoneExist(login.getPhone()))
        return RestResponse.failure(HttpCodeEnum.PHONE_NOT_EXIST);
        if(!StringUtils.hasText(login.getPassword()))
            return RestResponse.failure(HttpCodeEnum.PASSWORD_NOT_NULL);
        return userService.loginByPasswd(login);
    }

    //发送登录验证码
    @GetMapping("/sendLoginCode/{phone}")
    public RestResponse sendLoginCode(@PathVariable String phone, HttpServletRequest request) {
        if(!StringUtils.hasText(phone))
            return RestResponse.failure(HttpCodeEnum.PHONE_NOT_NULL);
        if(!userService.phoneExist(phone))
            return RestResponse.failure(HttpCodeEnum.PHONE_NOT_EXIST);
        String ip = request.getRemoteAddr();
        synchronized (ip.intern()){
            String userIp = redisTemplate.opsForValue().get(Const.LOGIN_CODE_IP + ip);
            if (userIp != null) throw new SystemException(HttpCodeEnum.CODE_SEND_FREQUENT);
            else {
                redisTemplate.opsForValue().set(Const.LOGIN_CODE_IP + ip, "1", 59, TimeUnit.SECONDS);
            }
            Random random = new Random();
            Integer code = random.nextInt(900000) + 100000;

            boolean flag = userService.sendCode(phone, code);

            if(flag){
                redisTemplate.opsForValue().set(Const.LOGIN_CODE + phone, code.toString(), 10, TimeUnit.MINUTES);
                return RestResponse.success("验证码发送成功");
            }
            return RestResponse.failure(HttpCodeEnum.MESSAGE_SEND_FAILURE);
        }
    }

    //注册
    @PostMapping("/register")
    public RestResponse register(@RequestBody RegisterDto register) {
        return userService.register(register);
    }

    //发送注册验证码
    @GetMapping("/sendRegisterCode/{phone}")
    public RestResponse sendRegisterCode(@PathVariable String phone, HttpServletRequest request){
        if(!StringUtils.hasText(phone))
            return RestResponse.failure(HttpCodeEnum.PHONE_NOT_NULL);
        if(!Pattern.matches("^1[3-9]\\d{9}$", phone))
            return RestResponse.failure(HttpCodeEnum.PHONE_ERROR);
        if(userService.phoneExist(phone))
            return RestResponse.failure(HttpCodeEnum.PHONE_EXIST);
        String ip = request.getRemoteAddr();
        synchronized (ip.intern()) {
            String userIp = redisTemplate.opsForValue().get(Const.REGISTER_CODE_IP + ip);
            if (userIp != null) throw new SystemException(HttpCodeEnum.CODE_SEND_FREQUENT);
            else {
                redisTemplate.opsForValue().set(Const.REGISTER_CODE_IP + ip, "1", 59, TimeUnit.SECONDS);
            }
            Random random = new Random();
            Integer code = random.nextInt(900000) + 100000;


            boolean flag = userService.sendCode(phone, code);


            if (flag) {
                redisTemplate.opsForValue().set(Const.REGISTER_CODE + phone, code.toString(), 10, TimeUnit.MINUTES);
                return RestResponse.success("验证码发送成功");
            }
            return RestResponse.failure(HttpCodeEnum.MESSAGE_SEND_FAILURE);
        }
    }

    //退出登录
    @GetMapping("logout")
    public RestResponse logout(HttpServletRequest request) {
        return userService.logout(request);
    }

    //忘记密码验证码
    @GetMapping("/sendForgetCode/{phone}")
    public RestResponse sendForgetCode(@PathVariable String phone, HttpServletRequest request){
        if(!StringUtils.hasText(phone))
            return RestResponse.failure(HttpCodeEnum.PHONE_NOT_NULL);
        if(!userService.phoneExist(phone))
            return RestResponse.failure(HttpCodeEnum.PHONE_NOT_EXIST);
        String ip = request.getRemoteAddr();
        synchronized (ip.intern()) {
            String userIp = redisTemplate.opsForValue().get(Const.FORGOT_CODE_IP + ip);
            if (userIp != null) throw new SystemException(HttpCodeEnum.CODE_SEND_FREQUENT);
            else {
                redisTemplate.opsForValue().set(Const.FORGOT_CODE_IP + ip, "1", 59, TimeUnit.SECONDS);
            }
            Random random = new Random();
            Integer code = random.nextInt(900000) + 100000;

            boolean flag = userService.sendCode(phone, code);

            if (flag) {
                redisTemplate.opsForValue().set(Const.FORGOT_CODE + phone, code.toString(), 10, TimeUnit.MINUTES);
                return RestResponse.success("验证码发送成功");
            }
            return RestResponse.failure(HttpCodeEnum.MESSAGE_SEND_FAILURE);
        }
    }

    @PostMapping("/forgetPassword")
    public RestResponse forgetPassword(@RequestBody ForGetPasswordDto forget) {
        return userService.forgetPassword(forget);
    }

    @PreAuthorize("@ps.hasPermission('user:query')")
    @GetMapping("/hello")
    public String hello() {
        System.out.println("hello world");
        return "hello world";
    }
    //查询个人信息
    @GetMapping("/getUserById/{id}")
    public RestResponse selectUser(@PathVariable Long id){
        return userService.selectUser(id);
    }



}
